#include "video.h"
#include "player.h"
#include <unistd.h>
#include <dirent.h>
#include "sys.h"


#define VIDEO_DIR "/overlay/videos/"

int thread_func(Video *obj);
void video_clear_screen(void);
bool video_get_state(void);
int video_get_volume(void);
void video_pause(void);
void video_play(const char *name);
void video_set_cur(int cur);
void video_set_volume(int volume);

//支持的视频文件格式
static const char *fileType[] = 
{
    ".avi", ".mkv", ".flv", ".ts", ".mp4", ".webm", "asf", "mpg", ".mpeg", ".mov", ".vob", ".3gp", ".wmv", ".pmp"
};

static MediaPlayer *gMplayer = nullptr;

/**
  *@brief Video构造函数
  *@param exit_cb 退出进程回调函数
  */
Video::Video(exit_cb_t exit_cb, mutex &UIMutex)
{
    thread_exit_flag = false;
    ui_mutex = &UIMutex;

    //设置UI回调函数
    gui_opt_t gui_opts = {0};
    gui_opts.exit_cb = exit_cb;
    gui_opts.video_clear_screen = video_clear_screen;
    gui_opts.video_get_state = video_get_state;
    gui_opts.video_get_volume = video_get_volume;
    gui_opts.video_pause = video_pause;
    gui_opts.video_play = video_play;
    gui_opts.video_set_cur = video_set_cur;
    gui_opts.video_set_volume = video_set_volume;

    video_gui_init(&gui_opts);

    pthread = new thread(thread_func, this);           //创建执行线程
}

Video::~Video()
{
    thread_exit_flag = true;
    pthread->join();
    delete pthread;

    video_gui_release();
}

/**
  *@brief 搜索某个目录下的视频文件,支持多种格式
  *@param path 目录路径
  *@return 搜索到的音乐个数
  */
int Video::searchVideo(string path)
{
    int cnt_r = 0;
    int i;
    bool legal_video = false;
    std::string file_path;

    struct dirent *ent;
    DIR *dir = opendir(path.c_str());

    for (i = 0; ; i++)
    {
        ent = readdir(dir);
        if (ent == NULL)
            break;

        if (ent->d_type == DT_REG)
        {
            const char *pfile = strrchr(ent->d_name, '.');
            if (pfile != NULL)
            {
                file_path = path + std::string(ent->d_name);

                for(int j = 0; j < sizeof(fileType) / sizeof(fileType[0]); j++)
                {
                    if (strcasecmp(pfile, fileType[j]) == 0)
                    {
                        printf("%s file\n",fileType[j]);
                        legal_video = true;
                        break;
                    }
                }
            }
        }
        if (legal_video == true)
        {
            legal_video = false;
            ui_mutex->lock();
            video_gui_add_video_list(ent->d_name);
            ui_mutex->unlock();
            
            cnt_r++;
        }

        usleep(50000);
    }

    closedir(dir);

    return cnt_r;
}

int thread_func(Video *obj)
{
    usleep(50000);

    gMplayer = new MediaPlayer();           //创建播放器

    obj->searchVideo(VIDEO_DIR);

    while (!obj->getExitFlag())
    {
        int cur = gMplayer->GetCurrent();
        int total = gMplayer->GetDuration();

        obj->getUIMutex()->lock();
        video_gui_set_progress(cur / 1000, total / 1000);
        obj->getUIMutex()->unlock();

        usleep(50000);
    }

    delete gMplayer;

    return 0;
}

/**
 * @brief UI清屏回调函数
 */
void video_clear_screen(void)
{
    sys_display_clear();
}

/**
 * @brief UI获取视频播放状态回调函数
 */
bool video_get_state(void)
{
    bool state = false;

    if(gMplayer != nullptr)
        state = gMplayer->GetState();

    return state;
}

/**
 * @brief UI获取音量回调函数
 */
int video_get_volume(void)
{
    int  volume = 0;

    if(gMplayer != nullptr)
        volume = gMplayer->GetVolume();

    return volume;
}

/**
 * @brief UI暂停视频毁掉寒酸
 */
void video_pause(void)
{
    if(gMplayer != nullptr)
        gMplayer->Pause();
}

/**
 * @brief UI播放视频回调函数
 */
void video_play(const char *name)
{
    if(name == NULL)
    {
        gMplayer->Start();      //继续播放
        return;
    }

    //播放新的视频
    string url = VIDEO_DIR + string(name);
    gMplayer->PlayNewVideo(url);
    gMplayer->Start();      
}

/**
 * @brief UI设置播放时间点回调函数
 */
void video_set_cur(int cur)
{
    if(gMplayer != nullptr)
        gMplayer->SetCurrent(cur * 1000);
}

/**
 * @brief UI设置音量回调函数
 */
void video_set_volume(int volume)
{
    if(gMplayer != nullptr)
        gMplayer->SetVolume(volume);
}

